package com.syh.jn.scm.service.impl.upstream.finance;

import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.alibaba.dubbo.config.annotation.Service;
import com.syh.core.ddd.event.annotation.DomainEventHandle;
import com.syh.core.ddd.infrastructure.repository.AggregateRepository;
import com.syh.core.ddd.service.AbstractServiceImpl;
import com.syh.jn.scm.domain.upstream.entity.finance.UpCostBill;
import com.syh.jn.scm.domain.upstream.entity.finance.UpStatementAccountBill;
import com.syh.jn.scm.domain.upstream.event.UpCostBillEvent;
import com.syh.jn.scm.domain.upstream.event.UpStatementAccountBillEvent;
import com.syh.jn.scm.domain.upstream.repository.finance.UpCostBillRepository;
import com.syh.jn.scm.dto.support.FilesDto;
import com.syh.jn.scm.dto.upstream.finance.UpCostBillVo;
import com.syh.jn.scm.service.api.upstream.finance.UpCostBillService;
import com.syh.jn.scm.service.api.upstream.finance.enums.UpCostBillEnum;
import com.syh.jn.scm.service.api.upstream.finance.enums.UpStatementAccountBillEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
public class UpCostBillServiceImpl extends AbstractServiceImpl<Object, Object, UpCostBillVo, UpCostBill, Long> implements UpCostBillService {

  @Autowired
  private UpCostBillRepository upCostBillRepositoryImpl;

  @Override
  protected AggregateRepository<UpCostBill, Long> getAggregateRepository() {
    return upCostBillRepositoryImpl;
  }

  /**
   * 确认生效
   *
   * @param id
   * @return
   */
  @Override
  public Boolean confirmState(Long id) {
    UpCostBill costBill = upCostBillRepositoryImpl.getById(id);
    costBill.confirmState();
    upCostBillRepositoryImpl.update(costBill);

    //双方都确认之后
    if (costBill.getState().equals(UpCostBillEnum.CONFIRM.getStatus()) && costBill.getConfirmState().equals(UpCostBillEnum.OTHERPARTY_CONFIRM.getStatus())) {
      this.publicEvent(UpCostBillEvent.buildUpCostBillStateConfirmEvent(new Object[]{costBill}));
    }
    return Boolean.TRUE;
  }

  /**
   * 取消确认生效
   *
   * @param id
   * @return
   */
  @Override
  public Boolean cancelConfirm(Long id) {
    UpCostBill costBill = upCostBillRepositoryImpl.getById(id);
    costBill.cancelConfirm();
    upCostBillRepositoryImpl.update(costBill);

    //有一方确认
    if (costBill.getState().equals(UpCostBillEnum.CONFIRM.getStatus())) {
      this.publicEvent(UpCostBillEvent.buildUpCostBillStateUnConfirmEvent(new Object[]{costBill}));
    }
    return Boolean.TRUE;
  }

  /**
   * 上传单据图片
   *
   * @param dto
   */
  @Override
  public void upload(FilesDto dto) {
    UpCostBill costBill = upCostBillRepositoryImpl.getById(dto.getId());
    costBill.upload(dto);
    upCostBillRepositoryImpl.upload(costBill);
  }

  /**
   * 消费者：监听对账单（生成对账单状态和对账单号）
   *
   * @param bill
   */
  @DomainEventHandle(UpStatementAccountBillEvent.UP_STATEMENT_BILL_ACCOUNT_CREATED)
  protected void handleUpStatementBillAccountCreated(UpStatementAccountBill bill) {
    bill.getUpStatementAccountBillItems().forEach(billItem -> {
      if (billItem.getSourceType().equals(UpStatementAccountBillEnum.SOURCE_COST_BILL.getStatus())) {
        UpCostBill costBill = upCostBillRepositoryImpl.getById(billItem.getSourceId());
        costBill.generating(bill.getId());
        upCostBillRepositoryImpl.upload(costBill);
      }
    });
  }

  /**
   * 消费者：监听对账单（修改对账单状态）
   *
   * @param bill
   */
  @DomainEventHandle(UpStatementAccountBillEvent.UP_STATEMENT_BILL_ACCOUNT_UPDATA)
  protected void handleUpStatementBillAccountUpdata(UpStatementAccountBill bill) {
    Wrapper wrapper = Wrapper.build();
    wrapper.append(Restrictions.eq("statementOfAccountId", bill.getId()));
    List<UpCostBill> costBills = upCostBillRepositoryImpl.getList(wrapper);
    costBills.forEach(upCostBill -> {
      upCostBill.cancelGenerating();
      upCostBillRepositoryImpl.upload(upCostBill);
    });
    bill.getUpStatementAccountBillItems().forEach(billItem -> {
      if (billItem.getSourceType().equals(UpStatementAccountBillEnum.SOURCE_COST_BILL.getStatus())) {
        UpCostBill costBill = upCostBillRepositoryImpl.getById(billItem.getSourceId());
        costBill.generating(bill.getId());
        upCostBillRepositoryImpl.upload(costBill);
      }
    });
  }

  /**
   * 消费者：监听对账单（删除对账单状态和对账单号）
   *
   * @param bill
   */
  @DomainEventHandle(UpStatementAccountBillEvent.UP_STATEMENT_BILL_ACCOUNT_DESTORY)
  protected void handleUpStatementBillAccountDestory(UpStatementAccountBill bill) {
    bill.getUpStatementAccountBillItems().forEach(billItem -> {
      if (billItem.getSourceType().equals(UpStatementAccountBillEnum.SOURCE_COST_BILL.getStatus())) {
        UpCostBill costBill = upCostBillRepositoryImpl.getById(billItem.getSourceId());
        costBill.cancelGenerating();
        upCostBillRepositoryImpl.upload(costBill);
      }
    });
  }
}
